#! /bin/sh

source /etc/rc.d/common

SCST_MODS="scst iscsi_scst isert_scst ib_srpt \
scst_disk scst_vdisk scst_tape scst_changer fcst"
SCST_CFG="/etc/scst.conf"
SCSTADMIN="/usr/sbin/scstadmin"
ISCSI_SCSTD="/usr/sbin/iscsi-scstd"
ISCSI_SCSTD_LOCK="/var/lock/iscsi-scstd"
FCOEMON="/usr/sbin/fcoemon"
FCOEMON_LOCK="/var/lock/fcoemon"

# Which Cavium/QLogic target module
if [ -f "/lib/modules/$(/bin/uname -r)/extra/qla2x00tgt.ko" ]; then
    SCST_MODS="${SCST_MODS} qla2x00tgt"
else
    SCST_MODS="${SCST_MODS} scst_qla2xxx"
fi

# For optional SCST modules
OPTL_MODS=""
if [ -f "/lib/modules/$(/bin/uname -r)/extra/atto_scst.ko" ]; then
    OPTL_MODS="${OPTL_MODS} atto_scst"
fi
if [ -f "/lib/modules/$(/bin/uname -r)/extra/ocs_fc_scst.ko" ]; then
    OPTL_MODS="${OPTL_MODS} ocs_fc_scst"
fi
if [ -f "/lib/modules/$(/bin/uname -r)/extra/chfcoe.ko" ]; then
    OPTL_MODS="${OPTL_MODS} chfcoe"
fi

check_args ${@}

load_kern_mods() {
    /bin/echo "Loading SCST kernel modules..."
    # Load the core SCST modules first
    for i in ${SCST_MODS}; do
        /sbin/modprobe ${i} || return 1
    done
    # Load the optional driver modules next (don't check exit status)
    for i in ${OPTL_MODS}; do
        /sbin/modprobe -s ${i}
    done
    return 0
}

unload_kern_mods() {
    /bin/echo "Unloading SCST kernel modules..."
    # Unload the optional driver modules first (don't check exit status)
    for i in $(/bin/echo ${OPTL_MODS} | /usr/bin/tr ' ' '\n' | \
        /usr/bin/tac | /usr/bin/tr '\n' ' '); do
        if [ -d /sys/module/${i} ]; then
            /sbin/rmmod -w ${i}
        fi
    done
    # Unload the core SCST modules next
    for i in $(/bin/echo ${SCST_MODS} | /usr/bin/tr ' ' '\n' | \
        /usr/bin/tac | /usr/bin/tr '\n' ' '); do
        /sbin/rmmod -w ${i} || return 1
    done
    return 0
}

start_user_progs() {
    /bin/echo "Starting SCST userland daemons..."
    ${ISCSI_SCSTD} || return 1
    /bin/touch ${ISCSI_SCSTD_LOCK}
    ${FCOEMON} -s || return 1
    /bin/touch ${FCOEMON_LOCK}
    return 0
}

stop_user_progs() {
    /bin/echo "Stopping SCST userland daemons..."
    /bin/kill -TERM $(/bin/pidof ${FCOEMON}) || return 1
    wait_for_stop ${FCOEMON} && /bin/rm -f ${FCOEMON_LOCK}
    /bin/kill -TERM $(/bin/pidof ${ISCSI_SCSTD}) || return 1
    wait_for_stop ${ISCSI_SCSTD} && /bin/rm -f ${ISCSI_SCSTD_LOCK}
    /bin/sleep 1
    return 0
}

apply_config() {
    if [ -f ${SCST_CFG} ]; then
        /bin/echo "Applying SCST configuration..."
        /usr/sbin/scstadmin -config ${SCST_CFG} -lip || return 1
    fi
    return 0
}

start() {
    # If our pre-SCST file exists, run it
    if [ -f /etc/pre-scst_xtra_conf ]; then
        /bin/echo "Pre-SCST user config. file found; running..."
        /bin/sh /etc/pre-scst_xtra_conf
    fi
    # Load the SCST core modules and target drivers
    load_kern_mods || exit 1
    # Start the iSCSI SCST daemon and daemons required for FCST
    start_user_progs || exit 1
    # Configure SCST (if it fails, stop SCST)
    apply_config || (stop_user_progs; unload_kern_mods; exit 1)
    # If our post-SCST file exists, run it
    if [ -f /etc/post-scst_xtra_conf ]; then
        /bin/echo "Post-SCST user config. file found; running..."
        /bin/sh /etc/post-scst_xtra_conf
    fi
}

stop() {
    # Stop all of the userland daemons
    stop_user_progs || exit 1
    # Unload all of the modules in reverse order
    unload_kern_mods || exit 1
}

status() {
    if [ -d "/sys/kernel/scst_tgt" ]; then
        exit ${RUNNING}
    else
        exit ${STOPPED}
    fi
}

# Perform specified action
${1}
